package managedbean;

import entity.CapacityControlEntity;
import entity.FnBBranchEntity;
import entity.StakeholderEntity;
import entity.TableTypeEntity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import javax.faces.model.SelectItem;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import session.stateful.TableSessionBean;
import exception.CapacityControlException;

/**
 *
 * @author Dell
 */
@ManagedBean
@SessionScoped
public class TableManagerBean {

    @EJB
    TableSessionBean tableSessionBean;
    private TableTypeEntity tableType;
    private CapacityControlEntity selectedCapacityControl = new CapacityControlEntity();
    private CapacityControlEntity capacityControl = new CapacityControlEntity();
    private List<CapacityControlEntity> listOfCapacityControl = new ArrayList<CapacityControlEntity>();
    private List<TableTypeEntity> listOfTableType;
    private List dayOfWeek = new ArrayList();
    private StakeholderEntity stakeholder;
    private FnBBranchEntity selectedBranch;
    private boolean reloadCapacityControl;
    private boolean reloadTableType;
    private FacesContext ctx = FacesContext.getCurrentInstance();

    public TableManagerBean() {
        reloadTableType = true;
        reloadCapacityControl = false;
        dayOfWeek.add(new SelectItem(0, "Default"));
        dayOfWeek.add(new SelectItem(1, "Sunday"));
        dayOfWeek.add(new SelectItem(2, "Monday"));
        dayOfWeek.add(new SelectItem(3, "Tuesday"));
        dayOfWeek.add(new SelectItem(4, "Wednesday"));
        dayOfWeek.add(new SelectItem(5, "Thursday"));
        dayOfWeek.add(new SelectItem(6, "Friday"));
        dayOfWeek.add(new SelectItem(7, "Saturday"));
        dayOfWeek.add(new SelectItem(8, "Specific Date"));
        reloadCapacityControl = true;
    }

    public void addCapacityControl(ActionEvent event) {
        try {
            tableSessionBean.addCapacityControl(tableType.getId(), capacityControl);
            capacityControl = new CapacityControlEntity();
            reloadCapacityControl = true;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Add Successfully", ""));
        } catch (CapacityControlException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Add Unsuccessfully: " + ex.getMessage(), ""));
        }
    }

    public void removeCapacityControl(long id) {
        tableSessionBean.removeCapacityControl(id);
        reloadCapacityControl = true;
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                FacesMessage.SEVERITY_INFO, "Remove Successfully", ""));
    }

    public void editCapacityControl(RowEditEvent event) {
        CapacityControlEntity temp = (CapacityControlEntity) event.getObject();
        try {
            tableSessionBean.editCapacityControl(temp);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Edit Successfully", ""));
            reloadCapacityControl = true;

        } catch (CapacityControlException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Edit Unsuccessfully: " + ex.getMessage(), ""));
        }
    }

    public void addTableType(ActionEvent event) {
        tableSessionBean.addTableType(selectedBranch.getId(), tableType);
        reloadTableType = true;
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                FacesMessage.SEVERITY_INFO, "Added table " + tableType.getName() + " successfully", ""));
    }

    public void initAddTableType(PhaseEvent event) throws IOException {
        if (!checkBranch()) {
            return;
        }
        if (reloadTableType) {
            tableType = new TableTypeEntity();
            reloadTableType = false;
        }
    }

    public void initTableTypeList(PhaseEvent event) throws IOException {
        if (!checkBranch()) {
            return;
        }
        listOfTableType = tableSessionBean.getAllTableType(selectedBranch.getId());
    }

    public void handleTableImageUpload(FileUploadEvent event) throws AbortProcessingException, NoSuchAlgorithmException {
        try {
            StakeholderEntity selectedStakeholder = (StakeholderEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholder");
            selectedBranch = (FnBBranchEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedBranch");
            System.out.println("Try to upload image");
            System.out.println(event.getFile().getFileName());
            String strDirectory = selectedStakeholder.getUsername();
            String branchDirectory = selectedBranch.getId().toString();
            String filePath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/images/upload/media/" + strDirectory + "/" + branchDirectory + "/table/");
            File result = new File(filePath + System.getProperty("file.separator") + event.getFile().getFileName().replace(" ", "_"));
            File file = new File(filePath);
            if (!file.exists()) {
                if ((new File(filePath)).mkdirs()) {
                    System.out.println("Directory: " + strDirectory + " created");
                }
            }
            FileOutputStream out = new FileOutputStream(result);
            int a;
            int BUFFER_SIZE = 8192;
            byte[] buffer = new byte[BUFFER_SIZE];
            InputStream is = event.getFile().getInputstream();
            while (true) {
                a = is.read(buffer);
                if (a < 0) {
                    break;
                }
                out.write(buffer, 0, a);
                out.flush();
            }
            tableType.setImageURL("upload/media/" + selectedStakeholder.getUsername() + "/" + selectedBranch.getId().toString() + "/table/" + event.getFile().getFileName().replace(" ", "_"));
            out.close();
            is.close();
            FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void initEditTableTypeInfo(PhaseEvent event) throws IOException {
        if (!checkTableType()) {
            return;
        }
        reloadTableType = true;
        initCapacityControl();
    }

    public void selectTable(SelectEvent event) {
        reloadCapacityControl = true;
    }

    public void editTableTypeInfo(ActionEvent event) throws IOException {
        tableSessionBean.editTableType(tableType);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                FacesMessage.SEVERITY_INFO, "Edit table " + tableType.getName() + " successfully: ", ""));
    }

    public void initCapacityControl() throws IOException {
        if (reloadCapacityControl) {
            System.out.println("check reload");
            listOfCapacityControl = tableSessionBean.getListOfCapacityControl(tableType.getId());
            Collections.sort(listOfCapacityControl, new CapacityControlEntity());
            reloadCapacityControl = false;
        }
    }

    public void onRowSelectEditTableType(SelectEvent event) throws IOException {
        reloadCapacityControl = true;
        String serverName = ctx.getExternalContext().getRequestServerName();
        int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
        String contextPath = ctx.getExternalContext().getRequestContextPath();
        ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/stakeholder/StakeholderEditTableTypeInfo.xhtml");
    }

    public TableTypeEntity getTableType() {
        return tableType;
    }

    public void setTableType(TableTypeEntity tableType) {
        this.tableType = tableType;
    }

    public List<CapacityControlEntity> getListOfCapacityControl() {
        return listOfCapacityControl;
    }

    public void setListOfCapacityControl(List<CapacityControlEntity> listOfCapacityControl) {
        this.listOfCapacityControl = listOfCapacityControl;
    }

    public CapacityControlEntity getCapacityControl() {
        return capacityControl;
    }

    public void setCapacityControl(CapacityControlEntity capacityControl) {
        this.capacityControl = capacityControl;
    }

    public List getDayOfWeek() {
        return dayOfWeek;
    }

    public void setDayOfWeek(List dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }

    public CapacityControlEntity getSelectedCapacityControl() {
        return selectedCapacityControl;
    }

    public void setSelectedCapacityControl(CapacityControlEntity selectedCapacityControl) {
        this.selectedCapacityControl = selectedCapacityControl;
    }

    public List<TableTypeEntity> getListOfTableType() {
        return listOfTableType;
    }

    public void setListOfTableType(List<TableTypeEntity> listOfTableType) {
        this.listOfTableType = listOfTableType;
    }

    public boolean checkStakeholder() throws IOException {
        stakeholder = (StakeholderEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholder");
        if (stakeholder == null || stakeholder.getId() == null) {
            String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/StakeholderLogin.xhtml");
            return false;
        }
        return true;
    }

    public boolean checkBranch() throws IOException {
        if (!checkStakeholder()) {
            return false;
        }
        selectedBranch = (FnBBranchEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedBranch");
        if (selectedBranch == null || selectedBranch.getId() == null) {
            String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/stakeholder/StakeholderViewAllBranch.xhtml");
        }
        return true;
    }

    public boolean checkTableType() throws IOException {
        if (!checkBranch()) {
            return false;
        }

        if (tableType == null || tableType.getId() == null) {
              String serverName = ctx.getExternalContext().getRequestServerName();
            int serverPort = (Integer) ctx.getExternalContext().getSessionMap().get("serverPort");
            String contextPath = ctx.getExternalContext().getRequestContextPath();
            ctx.getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/stakeholder/StakeholderViewAllTableType.xhtml");
            return false;
        }
        return true;
    }

    public void removeTableType(ActionEvent event) {
        String result = tableSessionBean.removeTableType(tableType, selectedBranch.getId());
        if (result.equals("Success")) {
            listOfTableType = tableSessionBean.getAllTableType(selectedBranch.getId());
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Remove table " + tableType.getName() + " successfully: ", ""));
            if (!listOfTableType.isEmpty()) {
                tableType = listOfTableType.get(0);
            } else {
                tableType = new TableTypeEntity();
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Can't remove because customers have booked this table type ", ""));
        }
    }
}
